/* Copyright (C) 
 * 
 * Disclaim
 * This program is the property of AI Speech Ltd. It shall be communicated to
 * authorized personnel only. It is not to be disclosed outside the group without
 * prior written consent. If you are not sure if you’re authorized to read this
 * program, please contact info@aispeech.com before reading.
 * 
 */

#include "wtk_utils_int_dict.h"
#include "wtk/utils/wtk_utils.h"


wtk_sds_int_dict_t* wtk_sds_int_dict_new(wtk_heap_t *heap) {
    wtk_sds_int_dict_t *dict = (wtk_sds_int_dict_t*)wtk_heap_zalloc(heap, sizeof(wtk_sds_int_dict_t));

    dict->heap = heap;
    dict->val  = wtk_str_hash_new(23);

    return dict;
}


void wtk_sds_int_dict_delete(wtk_sds_int_dict_t *dict) {
    if(dict->val) {
	wtk_str_hash_delete(dict->val);
    }
}


void wtk_sds_int_dict_reset(wtk_sds_int_dict_t *dict) {
    wtk_str_hash_reset(dict->val);
}



void wtk_sds_int_dict_set(wtk_sds_int_dict_t *dict, char *key, int len, int val) {
     hash_str_node_t *node = wtk_str_hash_find_node(dict->val, key, len, NULL);

     if(NULL==node) {
	 wtk_utils_hash_uniq_add(dict->val, key, len, (void*)(intptr_t)val);
     } else {
	 node->value = (void*)((intptr_t)val);
     }
}



void wtk_sds_int_dict_inc(wtk_sds_int_dict_t *dict, char *key, int len, int n) {
    hash_str_node_t *node = wtk_str_hash_find_node(dict->val, key, len, NULL);
    if(NULL==node) {
	wtk_utils_hash_uniq_add(dict->val, key, len, (void*)(intptr_t)n);
    } else {
	intptr_t tmp = (intptr_t)node->value;
	node->value = (void*)(tmp+n);
    }
}



void wtk_sds_int_dict_dec(wtk_sds_int_dict_t *dict, char *key, int len, int n) {
    hash_str_node_t *node = wtk_str_hash_find_node(dict->val, key, len, NULL);
    if(NULL==node) {
	wtk_utils_hash_uniq_add(dict->val, key, len, (void*)(intptr_t)(-n));
    } else {
	intptr_t tmp = (intptr_t)node->value;
	node->value = (void*)(tmp-n);
    }
}



int wtk_int_dic_get(wtk_sds_int_dict_t *dict, char *key, int len, int *recv) {
    hash_str_node_t *node = wtk_str_hash_find_node(dict->val, key, len, NULL);

    if(NULL==node) {
	return -1;
    } else {
	*recv = (intptr_t)node->value;
	return 0;
    }
}



wtk_array_t * wtk_sds_int_dict_sort(wtk_sds_int_dict_t *dict) {
    int len = wtk_str_hash_elems(dict->val);

    wtk_array_t *outArr = wtk_array_new_h(dict->heap, len, sizeof(hash_str_node_t*));

    wtk_str_hash_it_t iter = wtk_str_hash_iterator(dict->val);
    hash_str_node_t *node = wtk_str_hash_it_next(&iter);

    // copy value from dict to array, 
    while(node) {
	wtk_array_push2(outArr, &node);

	node = wtk_str_hash_it_next(&iter);
    }

    // sort in outArr
    int i;
    int j;
    int flag;
    hash_str_node_t *nodeP;
    hash_str_node_t *nodeN;
    hash_str_node_t *nodeT;
    
    for(i=0; i<len; ++i) {
	flag = 0;
	for(j=1; j<len-i; ++j) {
	    nodeP = wtk_utils_array_get_val(outArr, j-1, hash_str_node_t*);
	    nodeN = wtk_utils_array_get_val(outArr, j, hash_str_node_t*);

	    if((intptr_t)nodeP->value<(intptr_t)nodeN->value) {
		nodeT = nodeP;
		nodeP = nodeN;
		nodeN = nodeT;

		flag = 1;
	    }
	}

	if(0==flag) {
	    break;
	}
    }

    return outArr;
}



int wtk_sds_int_dict_get_val_num(wtk_sds_int_dict_t *dict) {
    if(NULL==dict || dict->val==NULL) {
        return 0;
    } else {
        return wtk_str_hash_elems(dict->val);
    }
}
